<template>
  <div class="demo">
    <div class="box" ref="box">
      <div
        class="scroll"
        ref="navScroll"
        @DOMMouseScroll="handleScroll"
        @mousewheel="handleScroll"
      >
        <div class="nav" ref="nav" :style="navStyle">
          <div
            class="tags"
            v-for="(item, index) in tags"
            :class="{ active: activeIndex === index }"
            :key="index"
            @click="handleClick(index)"
          >
            {{ item.title }}=={{ index + 1 }}
          </div>
        </div>
      </div>
    </div>
    <Button @click="handleAdd">添加</Button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      activeIndex: 0,
      navStyle: {
        transform: ""
      },
      tags: [
        {
          title: "标题"
        },
        {
          title: "标题"
        },
        {
          title: "标题"
        },
        {
          title: "标题"
        }
      ]
    };
  },
  mounted() {
    this.$nextTick(() => {
      // console.log(this.$refs.box.getBoundingClientRect());
    });
  },
  watch: {
    activeIndex() {
      this.$nextTick(() => {
        this.scrollToActiveTab();
      });
    }
  },
  methods: {
    handleAdd() {
      this.activeIndex = this.tags.length;
      this.tags.push({ title: "标题" });
    },
    handleClick(index) {
      this.activeIndex = index;
      this.$nextTick(() => {
        const activeTab = this.$el.querySelector(".active");
        // console.log(activeTab.getBoundingClientRect());
      });
    },
    handleScroll(e) {
      e.preventDefault();
      e.stopPropagation();
      const type = e.type;
      let delta = 0;
      if (type === "DOMMouseScroll" || type === "mousewheel") {
        delta = e.wheelDelta ? e.wheelDelta : -(e.detail || 0) * 40;
      }
      if (delta > 0) {
        this.scrollPrev();
      } else {
        this.scrollNext();
      }
    },
    scrollPrev() {
      const containerWidth = this.$refs.navScroll.offsetWidth;
      const currentOffset = this.getCurrentScrollOffset();
      if (!currentOffset) return;
      let newOffset =
        currentOffset > containerWidth ? currentOffset - containerWidth : 0;
      this.setOffset(newOffset);
    },
    scrollNext() {
      const navWidth = this.$refs.nav.offsetWidth;
      const containerWidth = this.$refs.navScroll.offsetWidth;
      const currentOffset = this.getCurrentScrollOffset();
      if (navWidth - currentOffset <= containerWidth) return;
      let newOffset =
        navWidth - currentOffset > containerWidth * 2
          ? currentOffset + containerWidth
          : navWidth - containerWidth;
      this.setOffset(newOffset);
    },
    getCurrentScrollOffset() {
      const { navStyle } = this;
      return navStyle.transform
        ? Number(navStyle.transform.match(/translateX\(-(\d+(\.\d+)*)px\)/)[1])
        : 0;
    },
    setOffset(value) {
      this.navStyle.transform = `translateX(-${value}px)`;
    },
    scrollToActiveTab() {
      // if (!this.scrollable) return;

      const nav = this.$refs.nav;
      const activeTab = this.$el.querySelector(`.active`);
      if (!activeTab) return;
      const navScroll = this.$refs.navScroll;
      const activeTabBounding = activeTab.getBoundingClientRect();
      console.log(activeTabBounding);
      const navScrollBounding = navScroll.getBoundingClientRect();
      const navBounding = nav.getBoundingClientRect();
      const currentOffset = this.getCurrentScrollOffset();
      let newOffset = currentOffset;
      if (navBounding.right < navScrollBounding.right) {
        newOffset = nav.offsetWidth - navScrollBounding.width;
      }
      if (activeTabBounding.right > navScrollBounding.right) {
        newOffset =
          currentOffset + activeTabBounding.right - navScrollBounding.right;
      } else if (activeTabBounding.left < navScrollBounding.left) {
        // newOffset = navScrollBounding.left;
        newOffset =
          currentOffset + (activeTabBounding.left - navScrollBounding.left);
      }
      //console.log(activeTabBounding.left < navScrollBounding.left);
      if (currentOffset !== newOffset) {
        this.setOffset(Math.max(newOffset, 0));
      }
    }
  }
};
</script>
<style lang="scss" scoped>
.box {
  width: 500px;
}
.scroll {
  display: flex;
  white-space: nowrap;
  overflow: hidden;
  .tags {
    padding: 0 15px;
    display: inline-block;
    &.active {
      background-color: pink;
    }
  }
}
</style>
